package com.donn.securitycontrolplatform.elefence.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.donn.securitycontrolplatform.common.Result;
import com.donn.securitycontrolplatform.db1.mapper.TElefenceMapper;
import com.donn.securitycontrolplatform.db1.mapper.TPositionInfoMapper;
import com.donn.securitycontrolplatform.db2.mapper.PersonMapper;
import com.donn.securitycontrolplatform.elefence.Response.Response;
import com.donn.securitycontrolplatform.elefence.entity.TElefence;
import com.donn.securitycontrolplatform.elefence.entity.TElefenceEquipment;
import com.donn.securitycontrolplatform.elefence.request.ElefenceCreateReq;
import com.donn.securitycontrolplatform.elefence.request.ElefenceQueryReq;
import com.donn.securitycontrolplatform.elefence.request.ElefenceUpdateReq;
import com.donn.securitycontrolplatform.elefence.service.ITElefenceEquipmentService;
import com.donn.securitycontrolplatform.elefence.service.ITElefenceService;
import com.donn.securitycontrolplatform.equipment.entity.TEquipment;
import com.donn.securitycontrolplatform.equipment.service.ITEquipmentService;
import com.donn.securitycontrolplatform.positioninformation.entity.TPositionInfo;
import com.donn.securitycontrolplatform.utils.ElefenceAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.geom.Point2D;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhenglx
 * @since 2022-06-21
 */
@Service
@Slf4j
public class TElefenceServiceImpl extends ServiceImpl<TElefenceMapper, TElefence> implements ITElefenceService {
    //删除状态
    public static final int DELETED_STATUS = 0;

    @Autowired
    TElefenceMapper tElefenceMapper;

    @Override
    public Response insertElefence(ElefenceCreateReq elefence) {
        Response result = new Response();
        result.setCode("100");
        result.setMsg("添加成功");
        result.setStatus(true);
        TElefence tElefence = new TElefence();
        BeanUtils.copyProperties(elefence, tElefence);
        try {
            save(tElefence);
            result.setRet(tElefence.getId());
        } catch (Exception e) {
            log.error("insertElefence error :", e);
            result.setMsg("添加失败");
            result.setStatus(false);
            result.setCode("500");
        }
        return result;
    }

    @Override
    public Response updateElefence(ElefenceUpdateReq elefence) {
        Response result = new Response();
        result.setCode("100");
        result.setMsg("修改成功");
        result.setStatus(true);
        TElefence tElefence = new TElefence();
        BeanUtils.copyProperties(elefence, tElefence);
        try {
            result.setRet(updateById(tElefence));
        } catch (Exception e) {
            log.error("updateElefence error :", e);
            result.setMsg("修改失败");
            result.setStatus(false);
            result.setCode("500");

        }
        return result;
    }

    @Override
    public Response deleteElefence(String elefenceId) {
        Response result = new Response();
        result.setCode("100");
        result.setMsg("删除成功");
        result.setStatus(true);
        try {
            result.setRet(removeById(elefenceId));
        } catch (Exception e) {
            log.error("deleteElefence error :", e);
            result.setMsg("删除失败");
            result.setStatus(false);
            result.setCode("500");
        }
        return result;
    }

    @Override
    public Response getElefenceById(String elefenceId) {
        Response result = new Response();
        result.setCode("100");
        result.setMsg("查询成功");
        result.setStatus(true);
        try {
            result.setRet(getById(elefenceId));
        } catch (Exception e) {
            log.error("insertRole error :", e);
            result.setCode("500");
            result.setMsg("查询失败");
            result.setStatus(false);
        }
        return result;
    }

    @Override
    public Response selectElefenceList(ElefenceQueryReq queryReq) {
        Response result = new Response();
        result.setCode("100");
        result.setMsg("查询成功");
        result.setStatus(true);
        try {
            QueryWrapper<TElefence> queryWrapper = new QueryWrapper();
            queryWrapper.lambda().eq(TElefence::getDeleted, DELETED_STATUS);
            if (queryReq.getName() != null) {
                queryWrapper.lambda().like(TElefence::getName, queryReq.getName());
            }
            result.setRet(list(queryWrapper));
        } catch (Exception e) {
            log.error("selectElefenceList error :", e);
            result.setCode("500");
            result.setMsg("查询失败");
            result.setStatus(false);
        }
        return result;
    }


    @Autowired
    ITEquipmentService equipmentService;

    @Autowired
    ITElefenceEquipmentService elefenceEquipmentService;

    @Override
    public Result entryEleFence(String tagId, String fenceId) {
        QueryWrapper<TEquipment> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(TEquipment::getTagId, tagId);
        TEquipment equipment = equipmentService.getOne(queryWrapper);
        if (equipment != null) {
            TElefenceEquipment elefenceEquipment = new TElefenceEquipment();
            elefenceEquipment.setCreateTime(LocalDateTime.now());
            elefenceEquipment.setFenceId(fenceId);
            elefenceEquipment.setEquipmentType(equipment.getRemark());
            elefenceEquipment.setTagid(tagId);
            elefenceEquipmentService.save(elefenceEquipment);
        }
        return Result.success("ok");
    }

    @Override
    public Result dynamicStatistics(int time, String fenceId, String equipmentType) {
        QueryWrapper<TElefenceEquipment> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(TElefenceEquipment::getFenceId, fenceId);
        queryWrapper.lambda().eq(TElefenceEquipment::getEquipmentType, equipmentType);
        queryWrapper.lambda().between(TElefenceEquipment::getCreateTime, LocalDateTime.now().plusMinutes(-time)
                , LocalDateTime.now());
        return Result.success(elefenceEquipmentService.count(queryWrapper));
    }

    @Autowired
    private TPositionInfoMapper positionInfoMapper;

    @Autowired
    private ITElefenceService elefenceService;

    @Override
    public Result dynamicStatisticsPersonQuantity(String fenceId) {
        //获取电子围栏区域
        List<Point2D.Double> pointList = getPoint2DList(fenceId);
        //获取全部人员标签
        List<String> tagIds = selectPersonTagIds();
        int quantity = 0;
        for (String tagId : tagIds) {
            //获取全部人员坐标信息
            TPositionInfo tPositionInfo = positionInfoMapper.getPositionInfoByTagId(tagId);
            if (tPositionInfo != null) {
                //获取全部人员坐标
                Point2D.Double point = getaPoint2Double(tPositionInfo.getPosition().split(",")[0], tPositionInfo.getPosition().split(",")[1]);
                if (ElefenceAlgorithm.isInArea(pointList, point)) {
                    quantity++;
                }
            }
        }
        return Result.success(quantity);
    }

    /**
     * 电子围栏数据库里记录的是x,y,z三维坐标，计算平面2D区域是不需要考虑z坐标
     * 故要去除positionArray[2][5][8][11]
     *
     * @param fenceId
     * @return
     */
    private List<Point2D.Double> getPoint2DList(String fenceId) {
        List<Point2D.Double> pointList = new ArrayList<>();
        TElefence elefence = elefenceService.getById(fenceId);
        if (elefence != null && elefence.getPosition() != null) {
            String position = elefence.getPosition();
            String[] positionArray = position.split(",");
            pointList.add(getaPoint2Double(positionArray[0], positionArray[1]));
            pointList.add(getaPoint2Double(positionArray[3], positionArray[4]));
            pointList.add(getaPoint2Double(positionArray[6], positionArray[7]));
            pointList.add(getaPoint2Double(positionArray[9], positionArray[10]));
        }
        return pointList;
    }

    private Point2D.Double getaPoint2Double(String x, String y) {
        Point2D.Double point = new Point2D.Double();
        point.x = Double.parseDouble(x);
        point.x = Double.parseDouble(y);
        return point;
    }

    @Autowired
    private PersonMapper personMapper;

    @DS("db2")
    private List<String> selectPersonTagIds() {
        return personMapper.selectPersonTagIds();
    }
}
